package cn.jlearn.proxy.web.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.UUID;
import cn.jlearn.proxy.web.enums.TunnelOnlineEnum;
import cn.jlearn.proxy.web.enums.TunnelProtocolEnum;
import cn.jlearn.proxy.web.enums.TunnelTypeEnum;
import cn.jlearn.proxy.web.enums.YesOrNoEnum;
import cn.jlearn.proxy.web.mapper.TunnelMapper;
import cn.jlearn.proxy.web.model.Tunnel;
import cn.jlearn.proxy.web.pojo.R;
import cn.jlearn.proxy.web.service.TunnelService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigInteger;
import java.util.Date;
import java.util.List;

/**
 * @author qianyingchao
 * @version 1.0
 * @date 2021/7/15 12:07 下午
 */
@Service
public class TunnelServiceImpl implements TunnelService {

    @Resource
    private TunnelMapper tunnelMapper;

    @Override
    public Tunnel getTunnelById(BigInteger id) {
        return tunnelMapper.selectById(id);
    }

    @Override
    public Tunnel getTunnelByToken(String token) {
        LambdaQueryWrapper<Tunnel> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Tunnel::getToken, token);
        queryWrapper.orderByDesc(Tunnel::getCreateTime);
        return tunnelMapper.selectOne(queryWrapper);
    }

    @Override
    public List<Tunnel> getTunnelList(String uid) {
        LambdaQueryWrapper<Tunnel> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Tunnel::getUid, uid);
        queryWrapper.orderByDesc(Tunnel::getCreateTime);
        return tunnelMapper.selectList(queryWrapper);
    }

    @Override
    public R<Tunnel> addTunnel(String uid, String tunnelName, String localHost, Integer localPort) {
        LambdaQueryWrapper<Tunnel> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Tunnel::getUid, uid);
        List<Tunnel> tunnels = tunnelMapper.selectList(queryWrapper);
        if (CollUtil.isNotEmpty(tunnels)) {
            return R.fail("416", "暂时只能创建一条隧道");
        }
        Tunnel tunnel = new Tunnel();
        tunnel.setUid(uid);
        tunnel.setType(TunnelTypeEnum.FREE.code);
        tunnel.setToken(UUID.randomUUID(true).toString(true));
        tunnel.setName(tunnelName);
        tunnel.setDomain(DateUtil.format(new Date(), DatePattern.PURE_DATETIME_MS_PATTERN) + ".proxy.jlearn.cn");
        tunnel.setProtocol(TunnelProtocolEnum.HTTP.getCode());
        tunnel.setLocalHost(localHost);
        tunnel.setLocalPort(localPort);
        tunnelMapper.insert(tunnel);
        return R.success(tunnel);
    }

    @Override
    public R<?> updateTunnel(BigInteger id, String uid, String tunnelName, String localHost, Integer localPort) {
        Tunnel tunnel = this.getTunnelById(id);
        if (tunnel != null && tunnel.getUid().equals(uid)) {
            Tunnel updateItem = new Tunnel();
            updateItem.setId(id);
            updateItem.setName(tunnelName);
            updateItem.setLocalHost(localHost);
            updateItem.setLocalPort(localPort);
            tunnelMapper.updateById(updateItem);
            return R.success();
        } else {
            return R.fail("416", "请勿操作他人数据");
        }
    }

    @Override
    public R<?> changeToken(BigInteger id, String uid) {
        Tunnel tunnel = this.getTunnelById(id);
        if (tunnel != null && tunnel.getUid().equals(uid)) {
            Tunnel updateItem = new Tunnel();
            updateItem.setId(id);
            updateItem.setToken(UUID.randomUUID(true).toString(true));
            tunnelMapper.updateById(updateItem);
            return R.success();
        } else {
            return R.fail("416", "请勿操作他人数据");
        }
    }

    @Override
    public R<?> online(String token, String online) {
        LambdaUpdateWrapper<Tunnel> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(Tunnel::getToken, token);
        Tunnel updateItem = new Tunnel();
        updateItem.setOnline(YesOrNoEnum.Y.code.equals(online) ? TunnelOnlineEnum.ONLINE.getCode() : TunnelOnlineEnum.OFFLINE.getCode());
        updateItem.setUpdateTime(new Date());
        tunnelMapper.update(updateItem, updateWrapper);
        return R.success();
    }

}
